@{title(CONF.name)}
@{layout('')}

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
	<meta http-equiv="X-UA-Compatible" content="IE=10" />
	<meta name="robots" content="all,follow" />
	@{import('spa.min@19.css', 'spa.min@19.js')}
	<script src="@{REPO.ui}"></script>
	@{import('meta', 'head', 'editor.min@1.css + editor.css + designer.css', 'filesaver.min.js + editor.min@1.js + uibuilder.min@1.js + func.js + editor.js', 'favicon.ico')}
</head>
<body@{if query.darkmode === '1'} class="ui-dark"@{fi}>

	<ui-component name="exec"></ui-component>
	<ui-component name="locale" config="requests:1;language:@{controller.language}"></ui-component>
	<ui-component name="windows" path="common.windows" config="zindex:50"></ui-component>
	<ui-component name="imageviewer"></ui-component>

	<ui-component name="LAZY prompt" config="cancel:@(Cancel);submit:@(OK)"></ui-component>
	<ui-component name="LAZY menu" config="style:2"></ui-component>
	<ui-component name="LAZY approve" config="cancel:@(Cancel)"></ui-component>
	<ui-component name="LAZY autocomplete"></ui-component>
	<ui-component name="LAZY message" config="style:2"></ui-component>
	<ui-component name="LAZY notify" config="position:bottom right"></ui-component>
	<ui-component name="LAZY notifybar"></ui-component>
	<ui-component name="LAZY fileuploader"></ui-component>
	<ui-component name="LAZY clipboard"></ui-component>
	<ui-component name="LAZY icons" config="list:@{#}/icons-db.html"></ui-component>
	<ui-component name="LAZY timepicker"></ui-component>
	<ui-component name="LAZY directory" config="placeholder:@(Search)"></ui-component>
	<ui-component name="LAZY colorpicker"></ui-component>
	<ui-component name="LAZY filereader"></ui-component>
	<ui-component name="LAZY floatinginput"></ui-component>
	<ui-component name="LAZY tooltip"></ui-component>
	<ui-component name="LAZY controls"></ui-component>
	<ui-component name="LAZY inlineproperties"></ui-component>
	<ui-component name="LAZY filesaver"></ui-component>

	<ui-component name="edit"></ui-component>
	<ui-component name="datepicker" config="today:@(Today);days:@(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);clear:@(Clear);months:@(January,February,March,April,May,Juny,July,August,September,October,November,December)"></ui-component>
	<ui-component name="markdown" config="highlight:false;charts:false"></ui-component>
	<ui-component name="paste"></ui-component>
	<ui-component name="shortcuts"></ui-component>
	<ui-component name="loading"></ui-component>
	<ui-component name="console" path="common.console" config="datasource:common.logs;clear:flow/reset"></ui-component>
	<ui-component name="datepicker" config="today:@(Today);days:@(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);clear:@(Clear);months:@(January,February,March,April,May,Juny,July,August,September,October,November,December)"></ui-component>

	<ui-component name="dropfiles" path="null" config="exec:flow/dropfiles" class="hidden">
		@(Drag &amp; Drop files here)
	</ui-component>

	<ui-component name="part" path="common.page" config="if:flow;url:@{#}/parts/flow.html;loading:0" class="hidden invisible"></ui-component>
	<ui-component name="part" path="common.page" config="if:componenteditor;url:@{#}/parts/component.html;invisible:1;reload:?/reload" class="hidden invisible"></ui-component>

	<ui-component name="importer" path="common.form" config="if:codereviewform;url:@{#}/forms/review.html"></ui-component>
	<ui-component name="importer" path="common.form" config="if:componentsform;url:@{#}/forms/components.html"></ui-component>
	<ui-component name="importer" path="common.form" config="if:sourcesform;url:@{#}/forms/sources.html"></ui-component>
	<ui-component name="importer" path="common.form" config="if:versionform;url:@{#}/forms/version.html"></ui-component>
	<ui-component name="importer" path="common.form" config="if:variablesform;url:@{#}/forms/variables.html"></ui-component>
	<ui-component name="importer" path="common.form" config="if:importform;url:@{#}/forms/import.html"></ui-component>
	<ui-component name="importer" path="common.form2" config="if:sourceform;url:@{#}/forms/source.html"></ui-component>

	<script>

		var common = {};

		DEF.fallback = '@{#}/cdn/j-{0}.html';
		DEF.versionhtml = '@{Flow.version}';

		ENVIRONMENT('designer');

		common.secret = 'flowstream';
		common.components = '@{PREF.components}';
		common.components2 = '@{PREF.components2}';
		common.language = '@{controller.language}';
		common.page = '';
		common.windows = [];

		// common.tms = '@{query.tms}' === '1';
		common.socket = '@{query.socket}';
		common.root = '@{#}';
		common.logs = {};
		common.logs.errors = { icon: 'ti ti-bug', name: '@(Errors)', encode: false, items: [] };
		common.page = common.socket ? 'flow' : '';

		@{if user.color}APPEARANCE({ color: '@{user.color}' });@{fi}

		ON('@flag showloading', function() {
			SETTER('loading/show');
		});

		ON('@flag hideloading', function() {
			SETTER('loading/hide', 1000);
		});

		$(W).on('message', function(e) {
			var data = e.originalEvent.data;
			if (data) {
				var msg = PARSE(data);
				if (msg && msg.TYPE) {
					switch (msg.TYPE) {
						case 'shortcut':
							SETTER('shortcuts/exec', msg.key);
							break;
						case 'darkmode':
							$('body').tclass('ui-dark', msg.value === true);
							break;
						case 'components':
							common.components = msg.value;
							break;
						case 'components2':
							common.components2 = msg.value;
							break;
					}
				}
			}
		});

		function saveshortcut(e) {

			var tag = e.target.tagName;
			if (tag === 'INPUT' || tag === 'TEXTAREA')
				return;

			var is = false;

			if (common.page === 'componenteditor' && !common.form && !common.form2) {
				EXEC('componenteditor/submit');
				is = true;
			} else if (common.form === 'noteform') {
				EXEC('noteform/submit');
				is = true;
			} else if (common.form === 'settings' && !FIND('#flowsettings').find('button[name="submit"]').prop('disabled')) {
				EXEC('flow/settings_submit');
				is = true;
			} else if (common.page === 'flow' && !common.form && !common.form2) {
				EXEC('flow/submit');
				is = true;
			}
			is && e && e.preventDefault();
		}

		SETTER(true, 'shortcuts/register', 'F1', function() {
			W.parent.postMessage(STRINGIFY({ TYPE: 'F1', SOURCE: 'flow' }));
		}, true);

		SETTER(true, 'shortcuts/register', 'F10', function(e) {
			W.parent.postMessage(STRINGIFY({ TYPE: 'F10', SOURCE: 'flow' }));
			e.preventDefault();
			e.stopPropagation();
		});

		SETTER(true, 'shortcuts/register', 'CMD+F, CTRL+F', function(e) {

			var tag = e.target.tagName;
			if (tag === 'INPUT' || tag === 'TEXTAREA')
				return;

			if (common.page === 'flow' && !common.form && !common.form2) {
				$('.ui-layout-left').find('input').focus();
				e.preventDefault();
			}
		});

		EXEC(true, '-shortcuts/register', 'CMD+ENTER, CTRL+ENTER', saveshortcut);

		EXEC(true, '-shortcuts/register', 'CMD+D, CTRL+D', function(e) {

			var tag = e.target.tagName;
			if (tag === 'INPUT' || tag === 'TEXTAREA')
				return;

			if (common.page === 'flow' && !common.form && !common.form2) {
				EXEC('flow/clone');
				e.preventDefault();
				e.stopPropagation();
			}
		}, true);

		EXEC(true, '-shortcuts/register', 'CMD+C, CTRL+C', function(e) {

			var tag = e.target.tagName;
			if (tag === 'INPUT' || tag === 'TEXTAREA')
				return;

			if (!window.getSelection().toString() && common.page === 'flow' && !common.form && !common.form2 && flow.selected) {
				EXEC('flow/copy_components');
				e.preventDefault();
				e.stopPropagation();
			}
		});

		EXEC(true, '-shortcuts/register', 'CMD+V, CTRL+V', function(e) {

			var tag = e.target.tagName;
			if (tag === 'INPUT' || tag === 'TEXTAREA')
				return;

			if (common.page === 'flow' && !common.form && !common.form2 && (e.target.nodeName !== 'INPUT' && e.target.nodeName !== 'TEXTAREA')) {
				EXEC('flow/paste_components', { x: 0, y: 0 }, true);
				e.preventDefault();
				e.stopPropagation();
			}
		});

		EXEC(true, '-shortcuts/register', 'remove', function(e) {

			var tag = e.target.tagName;
			if (tag === 'INPUT' || tag === 'TEXTAREA')
				return;

			if (common.page === 'flow' && !common.form && !common.form2) {
				Designer.CMD('flow.selected.clear');
				SET('flow.changed', true);
				e.preventDefault();
			}
		});

		EXEC(true, '-shortcuts/register', 'save', saveshortcut, true);

		EXEC(true, '-shortcuts/register', 'CMD+A, CTRL+A', function(e) {

			var tag = e.target.tagName;
			if (tag === 'INPUT' || tag === 'TEXTAREA')
				return;

			var designer = FIND('flow');
			var selected = designer.selected();
			if (!selected.components.length) {
				var keys = Object.keys(flow.data);
				for (var key in keys) {
					if (key !== 'groups' && key !== 'paused')
						designer.op.select(key, true);
				}
			} else
				select_connected(flow.selected);
		}, false, function(e) {
			var is = common.page === 'flow' && !common.form && !common.form2 && (!e.target || (e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA'));
			is && e.preventDefault();
			return is;
		});

		EXEC(true, '-exec/register', function(attr, el, e, type) {
			var c = attr.charAt(0);
			if (c === '=' || c === '/') {
				var id = ATTRD(el);
				var instance = flowinstances.instances[id];
				if (!instance && common.form === 'settings')
					instance = flowinstances.instances[flow.settingsinstanceid];
				if (instance) {
					attr = attr.substring(1);
					instance[attr] && instance[attr](el, e);
				}
				return true;
			}
		});

		function select_connected(comp) {
			var conns = comp.connections;
			if (!conns)
				return;
			var designer = FIND('flow');
			Object.keys(conns).forEach(output => {
				for (let com of conns[output]) {
					designer.op.select(com.id, true);
					select_connected(flow.data[com.id]);
				}
			});
		}

		// Error handling
		ON('ERROR', function(response) {

			if (!(response instanceof Array))
				response = [response];

			var err = [];
			var login = false;
			for (var m of response) {
				if (m.name === '401')
					login = true;
				err.push(m.error);
			}

			SETTER('message/warning @hideloading', err.join('<br />'));
			login && location.reload(true);
		});

	</script>

</body>
</html>